/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "hx711.h"
#include "string.h"
#include "ring_buff.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
    HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}

uint32_t uid[3];

uint8_t  USART_TX_BUF[200];
#define usart2_print(...)  HAL_UART_Transmit(&huart2,USART_TX_BUF,sprintf((char *)USART_TX_BUF,__VA_ARGS__),0xFFFF)

#define MAX_CLI_STRING 400
uint8_t rx_buffer = '\000';
uint8_t rx_string[MAX_CLI_STRING];
uint8_t rx_complete = 0;
uint8_t cmd_len;
uint8_t cmd[MAX_CLI_STRING];
int rx_index = 0;
float Weight = 0;
uint8_t receive_buff[255]; 


//for usart2
uint8_t rx_buffer2 = '\000';
uint8_t rx_string2[MAX_CLI_STRING];
uint8_t rx_complete2 = 0;
uint8_t cmd_len2;
uint8_t cmd2[MAX_CLI_STRING];
int rx_index2 = 0;
uint8_t receive_buff2[255]; 

#define SW_STAT_ON GPIO_PIN_RESET
#define SW_STAT_OFF GPIO_PIN_SET
#define SW1_ON   0x10
#define SW1_OFF  0x11
#define SW2_ON   0x12
#define SW2_OFF  0x13
#define SW3_ON   0x14
#define SW3_OFF  0x15
#define SW4_ON   0x16
#define SW4_OFF  0x17
#define SW5_ON   0x18
#define SW5_OFF  0x19
#define SW6_ON   0x1A
#define SW6_OFF  0x1B
#define SW7_ON   0x1C
#define SW7_OFF  0x1D

#define SW1_PIN GPIO_PIN_13
#define SW1_PORT GPIOC
#define SW2_PIN GPIO_PIN_9
#define SW2_PORT GPIOB
#define SW3_PIN GPIO_PIN_8
#define SW3_PORT GPIOB
#define SW4_PIN GPIO_PIN_7
#define SW4_PORT GPIOB
#define SW5_PIN GPIO_PIN_6
#define SW5_PORT GPIOB
#define SW6_PIN GPIO_PIN_5
#define SW6_PORT GPIOB
#define SW7_PIN GPIO_PIN_4
#define SW7_PORT GPIOB

//bluetooth chip
#define BT_MODE_PIN GPIO_PIN_14
#define BT_MODE_PORT GPIOB

#define BALANCE1_ZERO 0x1E
#define BALANCE1_CAL 0x1F
#define BALANCE2_ZERO 0x20
#define BALANCE2_CAL 0x21
#define GET_STATUS "GET_STATUS"

#define SET_NAME "SET_NAME"
#define REBOOT  0x24
#define GET_UID "GET_UID"
#define GET_MAC "GET_MAC"

int current_channel = 1;

uint32_t start_time1;
uint32_t end_time1;

uint32_t start_time6;
uint32_t end_time6;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#define APPLICATION_ADDRESS     (uint32_t)0x08003000
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
#if   (defined ( __CC_ARM ))
__IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));
#elif (defined (__ICCARM__))
#pragma location = 0x20000000
__no_init __IO uint32_t VectorTable[48];
#elif defined   (  __GNUC__  )
__IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));
#endif
void IAP_Set()
{
	uint32_t i = 0;
  /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/  

  /* Copy the vector table from the Flash (mapped at the base of the application
     load address 0x08004000) to the base address of the SRAM at 0x20000000. */
  for(i = 0; i < 48; i++)
  {
    VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));
  }

  /* Enable the SYSCFG peripheral clock*/
  __HAL_RCC_SYSCFG_CLK_ENABLE(); 
  /* Remap SRAM at 0x00000000 */
  __HAL_SYSCFG_REMAPMEMORY_SRAM();
}	
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */
  

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
  IAP_Set();
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_TIM3_Init();
  MX_USART2_UART_Init();
  MX_TIM6_Init();
  /* USER CODE BEGIN 2 */
	RingBuff_Init();
	//close the oil_pump
	//__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
	__HAL_UART_FLUSH_DRREGISTER(&huart1);
	HAL_UART_Receive_DMA(&huart1, &rx_buffer, 1);
	
	__HAL_UART_FLUSH_DRREGISTER(&huart2);
	HAL_UART_Receive_DMA(&huart2, &rx_buffer2, 1);
	
	__HAL_TIM_CLEAR_FLAG(&htim3, TIM_SR_UIF);
	//control hx711 rate
  HAL_GPIO_WritePin(HX711_RATE_PORT, HX711_RATE_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(BT_MODE_PORT, BT_MODE_PIN, GPIO_PIN_SET);
	HAL_Delay(100);
	Get_Tare(1);

	HAL_Delay(100);
	Get_Tare(2);
	HAL_Delay(100);
	Get_Cal(1);
	HAL_Delay(100);
	Get_Cal(2);
	
	HAL_Delay(1000);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	printf("STAT=APP\n");
	HAL_Delay(500);
	//reduce the priority for time6,because usart cmd is more important,wenfeng add
  HAL_NVIC_SetPriority(TIM6_IRQn, 3, 0);
  HAL_NVIC_EnableIRQ(TIM6_IRQn);
	Start_TIM();
	start_time6 = HAL_GetTick();
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		//usart2 receiver
		if(rx_complete2)
		{
			rx_complete2 = 0;
			//usart2_print("stm32 receive %s cmd, len is %d\n", cmd2, cmd_len2);
			//get uid
			if (cmd_len2 == strlen(GET_UID) && strncmp((char*)cmd2, GET_UID, cmd_len2) == 0) {
				HAL_GetUID(uid);
				usart2_print("uid=%08x%08x%08x\n",uid[0], uid[1], uid[2]);
			}
			//get status
			if (cmd_len2 == strlen(GET_STATUS) && strncmp((char*)cmd2, GET_STATUS, cmd_len2) == 0) {
				usart2_print("STAT=APP\n");
			}
			
			//get mac
			if (cmd_len2 == strlen(GET_MAC) && strncmp((char*)cmd2, GET_MAC, cmd_len2) == 0) {
					HAL_Delay(500);
					HAL_GPIO_WritePin(BT_MODE_PORT, BT_MODE_PIN, GPIO_PIN_RESET);
					printf("AT+LADDR\r\n");
					HAL_Delay(1000);
					HAL_GPIO_WritePin(BT_MODE_PORT, BT_MODE_PIN, GPIO_PIN_SET);
			}
			//set uid
			if (strstr((char*)cmd2, SET_NAME) != NULL) {
				if (cmd_len2 > strlen(SET_NAME) + strlen("="))
				{
				  usart2_print("%s=OK\n", cmd2 + strlen(SET_NAME) + strlen("="));
					HAL_GPIO_WritePin(BT_MODE_PORT, BT_MODE_PIN, GPIO_PIN_RESET);
					printf("AT+NAME%s\r\n", cmd2 + strlen(SET_NAME) + strlen("="));
					HAL_Delay(1000);
					HAL_GPIO_WritePin(BT_MODE_PORT, BT_MODE_PIN, GPIO_PIN_SET);
				}
				
			}
			
		}
		
		if (rx_complete)
		{
			rx_complete = 0;
			//get status
			if (cmd_len == strlen(GET_STATUS) && strncmp((char*)cmd, GET_STATUS, cmd_len) == 0) {
				printf("STAT=APP\n");
			}
			
			//return mac
			if (strstr((char*)cmd, "+LADDR") != NULL) {
				  usart2_print("%s\n", cmd);
			}
		}

		Weight = Get_Weight_immediately(current_channel);
		Weight = (float)Weight/1000.0;
		printf("blc%d=%0.3f kg\n", current_channel, Weight);
		if (current_channel == 1) {
			current_channel = 2;
		} else if (current_channel == 2) {
			current_channel = 1;
		}

  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
void Deal_Uart1_Cmd()
{
	//control oil pump
	//handle Cmd from app
	//usart1 receiver
	uint8_t buff[MAX_CLI_STRING]= {0} ;
	uint8_t ring_len = Get_RingBuff_Length();
	if (ring_len > 0)
	{
			printf("ring_len=%d\n", ring_len);
	}
	uint8_t buff_len = Read_Cmd(buff);
	//printf("buff_len=%d, buf=%d\n", buff_len, buff[0]);

	if (buff_len == 1 && buff[0] == SW1_ON) {
		HAL_GPIO_WritePin(SW1_PORT, SW1_PIN, SW_STAT_ON);
		printf("SW1=ON\n");
	} else if (buff_len == 1 && buff[0] == SW1_OFF) {
		HAL_GPIO_WritePin(SW1_PORT, SW1_PIN, SW_STAT_OFF);
		printf("SW1=OFF\n");
	} else if (buff_len == 1 && buff[0] == SW2_ON) {
		HAL_GPIO_WritePin(SW2_PORT, SW2_PIN, SW_STAT_ON);
		printf("ring_len=%d\n", ring_len);
		printf("SW2=ON\n");
	} else if (buff_len == 1 && buff[0] == SW2_OFF) {
		HAL_GPIO_WritePin(SW2_PORT, SW2_PIN, SW_STAT_OFF);
		printf("SW2=OFF\n");
	} else if (buff_len == 1 && buff[0] == SW3_ON) {
		HAL_GPIO_WritePin(SW3_PORT, SW3_PIN, SW_STAT_ON);
		printf("SW3=ON\n");
	} else if (buff_len == 1 && buff[0] == SW3_OFF) {
		HAL_GPIO_WritePin(SW3_PORT, SW3_PIN, SW_STAT_OFF);
		printf("SW3=OFF\n");
	} else if (buff_len == 1 && buff[0] == SW4_ON) {
		HAL_GPIO_WritePin(SW4_PORT, SW4_PIN, SW_STAT_ON);
		printf("SW4=ON\n");
	} else if (buff_len == 1 && buff[0] == SW4_OFF) {
		HAL_GPIO_WritePin(SW4_PORT, SW4_PIN, SW_STAT_OFF);
		printf("SW4=OFF\n");
	} else if (buff_len == 1 && buff[0] == SW5_ON) {
		HAL_GPIO_WritePin(SW5_PORT, SW5_PIN, SW_STAT_ON);
		printf("SW5=ON\n");
	} else if (buff_len == 1 && buff[0] == SW5_OFF) {
		HAL_GPIO_WritePin(SW5_PORT, SW5_PIN, SW_STAT_OFF);
		printf("SW5=OFF\n");
	} else if (buff_len == 1 && buff[0] == SW6_ON) {
		HAL_GPIO_WritePin(SW6_PORT, SW6_PIN, SW_STAT_ON);
		printf("SW6=ON\n");
	} else if (buff_len == 1 && buff[0] == SW6_OFF) {
		HAL_GPIO_WritePin(SW6_PORT, SW6_PIN, SW_STAT_OFF);
		printf("SW6=OFF\n");
	} else if (buff_len == 1 && buff[0] == SW7_ON) {
		HAL_GPIO_WritePin(SW7_PORT, SW7_PIN, SW_STAT_ON);
		printf("SW7=ON\n");
	} else if (buff_len == 1 && buff[0] == SW7_OFF) {
		HAL_GPIO_WritePin(SW7_PORT, SW7_PIN, SW_STAT_OFF);
		printf("SW7=OFF\n");
	}
	//balance operation
	if (buff_len == 1 && buff[0] == BALANCE1_ZERO) {
		Zero_Balance(1);
		printf("stm32 zero blance1\n");
	} else if (buff_len == 5 && buff[0] == BALANCE1_CAL) {
		int32_t cal_weight = buff[1] + (buff[2] << 8) + (buff[3] << 16) + (buff[4] << 24);
		Cal_Balance(1, cal_weight);
		printf("stm32 cal blance1 %d\n", cal_weight);
	} else if (buff_len == 1 && buff[0] == BALANCE2_ZERO) {
		Zero_Balance(2);
		printf("stm32 zero blance2\n");
	} else if (buff_len == 5 && buff[0] == BALANCE2_CAL) {
		int32_t cal_weight = buff[1] + (buff[2] << 8) + (buff[3] << 16) + (buff[4] << 24);
		Cal_Balance(2, cal_weight);
		printf("stm32 cal blance2 %d\n", cal_weight);
	}

	//reboot
	if (cmd_len == 1 && buff[0] == REBOOT) {
		printf("REBOOT\n");
		//HAL_Delay(100);
		NVIC_SystemReset();
	}
}

void HAL_GetUID(uint32_t *UID)
{
  UID[0] = (uint32_t)(READ_REG(*((uint32_t *)UID_BASE)));
  UID[1] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 4U))));
  UID[2] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 8U))));
}


void Start_TIM(void)
{
	//	HAL_TIM_Base_Stop_IT(&htim6);
	//__HAL_TIM_SET_COUNTER(&htim6,0);
	//__HAL_TIM_CLEAR_FLAG(&htim6, TIM_FLAG_UPDATE);
	HAL_TIM_Base_Start_IT(&htim6);
}


 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* Prevent unused argument(s) compilation warning */
	if (htim->Instance == TIM6)
	{
		//end_time6 = HAL_GetTick();
		//printf("timer6 up,expand %d", end_time6 - start_time6);
		Deal_Uart1_Cmd();
		//start_time6 = HAL_GetTick();
	} else if (htim->Instance == TIM1)
	{
		end_time1 = HAL_GetTick();
		printf("time up,start %d, end %d,expand %d,index %d", start_time1, end_time1, end_time1 - start_time1, rx_index);
		USART_DATA_Handler(&huart1, 1);
	}

}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 
{
	USART_DATA_Handler(huart, 0);
}


void USART_DATA_Handler(UART_HandleTypeDef *huart, uint8_t timeup) 
{
	if (huart->Instance == USART1) 
	{
		__HAL_UART_FLUSH_DRREGISTER(&huart1);
		if (rx_buffer == '\n' || timeup) 
		{
			HAL_TIM_Base_Stop_IT(&htim3);
			for(int i = 0; i < rx_index; i++)
			{
				cmd[i] = rx_string[i];
			}
			cmd[rx_index] = 0;
			cmd_len = rx_index;
			rx_complete = 1;
			rx_index = 0;
			for(int i = 0; i < MAX_CLI_STRING; i++) rx_string[i] = 0;
			//Deal_Cmd();
			//Write_RingBuff(cmd);
			uint8_t result = Write_Cmd(cmd, cmd_len);
			printf("w=%d,r=%d,l=%d\n", cmd[0], result, Get_RingBuff_Length());
		} 
		else 
		{
			//while(__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_UPDATE));
			if (rx_index >= MAX_CLI_STRING) 
			{
				rx_index = 0;
				for(int i = 0; i < MAX_CLI_STRING; i++) rx_string[i] = 0;
			}
			rx_string[rx_index] = rx_buffer;
			rx_index++;
			start_time1 = HAL_GetTick();
			HAL_TIM_Base_Stop_IT(&htim3);
			__HAL_TIM_SET_COUNTER(&htim3,0);
			__HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);
			HAL_TIM_Base_Start_IT(&htim3);

		}
	}
	
	
	//for usart2
	if (huart->Instance == USART2) 
	{
		__HAL_UART_FLUSH_DRREGISTER(&huart2);
		if (rx_buffer2 == '\n') 
		{
			for(int i = 0; i < rx_index2; i++)
			{
				cmd2[i] = rx_string2[i];
			}
			cmd2[rx_index2] = 0;
			cmd_len2 = rx_index2;
			rx_complete2 = 1;
			rx_index2 = 0;
			for(int i = 0; i < MAX_CLI_STRING; i++) rx_string2[i] = 0;
		} 
		else 
		{
			//while(__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_UPDATE));
			if (rx_index2 >= MAX_CLI_STRING) 
			{
				rx_index2 = 0;
				for(int i = 0; i < MAX_CLI_STRING; i++) rx_string2[i] = 0;
			}
			rx_string2[rx_index2] = rx_buffer2;
			rx_index2++;
		}
	}
	
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
	if (GPIO_Pin == GPIO_PIN_13)
	{
		delay_ms(50);
		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13)== 0)
		{
			usart2_print("disconnected!\n");
		}	
		else 
		{
			usart2_print("connected!\n");
		}
		
		//HAL_UART_Transmit(&huart2 , (uint8_t *)"hehe", 4, 0xFFFF);
		
	}
}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(char *file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
